package cn.com.klun.tjy.other.ThreadsTest;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class Resource {
    private int i = 0;
    private final ReentrantLock lock = new ReentrantLock();//重入锁
    private final Condition condition = lock.newCondition();
    public void incr(){
        lock.lock();//上锁
        try {
            // 这里不用if是避免多线程中，杜绝可能累加、递减会进行多次的可能
            while (i!=0){
                // 叫停，等待唤醒的信号---这个是什么等待
                condition.await();
            }
            i++;
            System.out.println("递增："+i);
            // 给其他添加信号
            condition.signalAll();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            // 解锁
            lock.unlock();
        }
    }
    public void decr(){
        try {
            //上锁
            lock.lock();
            while (i==0){
                //叫停，等待递增的信号
                condition.await();
            }
            // i != 0 可以获取到递增的信号
            i--;
            System.out.println("递减："+i);
            // 给其他信号
            condition.signalAll();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            //解锁
            lock.unlock();
        }
    }

    public static void main(String[] args) {
        ExecutorService service = Executors.newFixedThreadPool(10);
        Resource resource = new Resource();// 含有递增和递减的一个worker
        //四个线程 两个生产者 两个消费者
        service.submit(new IncrThread(resource));
        service.submit(new DecrThread(resource));
        service.submit(new IncrThread(resource));
        service.submit(new DecrThread(resource));
        service.shutdown();
        try {
            service.awaitTermination(300, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

}
class IncrThread extends Thread{
    private Resource resource;
    public IncrThread(Resource resource){
        this.resource = resource;
    }

    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            //每次停顿
            try{
                Thread.sleep(500);
            } catch (Exception e){
                e.printStackTrace();
            }
            resource.incr();
        }
    }
}
class DecrThread extends Thread{
    private Resource resource;
    public DecrThread(Resource resource){
        this.resource = resource;
    }

    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            resource.decr();
        }
    }
}
